package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.BilletTempHistory;
import com.ruoyi.business.mapper.BilletTempHistoryMapper;
import com.ruoyi.business.service.IBilletTempHistoryService;
import com.ruoyi.business.vo.BaseVo;
import com.ruoyi.business.vo.BaseWaterVo;
import com.ruoyi.business.vo.BilletTHistoryTemplateVo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 钢坯温度历史记录Service业务层处理
 * 
 * @author qiancheng
 * @date 2025-09-07
 */
@Service
public class BilletTempHistoryServiceImpl extends ServiceImpl<BilletTempHistoryMapper, BilletTempHistory> implements IBilletTempHistoryService
{
    @Autowired
    private BilletTempHistoryMapper billetTempHistoryMapper;

    /**
     * 查询钢坯温度历史记录
     * 
     * @param id 钢坯温度历史记录主键
     * @return 钢坯温度历史记录
     */
    @Override
    public BilletTempHistory selectBilletTempHistoryById(Long id)
    {
        return billetTempHistoryMapper.selectBilletTempHistoryById(id);
    }

    /**
     * 查询钢坯温度历史记录列表
     * 
     * @param billetTempHistory 钢坯温度历史记录
     * @return 钢坯温度历史记录
     */
    @Override
    public List<BilletTempHistory> selectBilletTempHistoryList(BilletTempHistory billetTempHistory)
    {
        return billetTempHistoryMapper.selectBilletTempHistoryList(billetTempHistory);
    }

    /**
     * 新增钢坯温度历史记录
     * 
     * @param billetTempHistory 钢坯温度历史记录
     * @return 结果
     */
    @Override
    public int insertBilletTempHistory(BilletTempHistory billetTempHistory)
    {
        billetTempHistory.setCreateTime(DateUtils.getNowDate());
        return billetTempHistoryMapper.insert(billetTempHistory);
    }

    /**
     * 修改钢坯温度历史记录
     * 
     * @param billetTempHistory 钢坯温度历史记录
     * @return 结果
     */
    @Override
    public int updateBilletTempHistory(BilletTempHistory billetTempHistory)
    {
        billetTempHistory.setUpdateTime(DateUtils.getNowDate());
        return billetTempHistoryMapper.updateBilletTempHistory(billetTempHistory);
    }

    /**
     * 批量删除钢坯温度历史记录
     * 
     * @param ids 需要删除的钢坯温度历史记录主键
     * @return 结果
     */
    @Override
    public int deleteBilletTempHistoryByIds(Long[] ids)
    {
        return billetTempHistoryMapper.deleteBilletTempHistoryByIds(ids);
    }

    /**
     * 删除钢坯温度历史记录信息
     * 
     * @param id 钢坯温度历史记录主键
     * @return 结果
     */
    @Override
    public int deleteBilletTempHistoryById(Long id)
    {
        return billetTempHistoryMapper.deleteBilletTempHistoryById(id);
    }


    @Override
    public BaseWaterVo getBilletTempHistoryData(int type) {
        // 1. 查询最近200条
        List<BilletTempHistory> list = billetTempHistoryMapper.selectRecent200(type);

        // 2. 隔行取100条
        List<BilletTempHistory> filtered = new ArrayList<>();
        if (type==2) {
            for (int i = 0; i < list.size(); i++) {
                filtered.add(list.get(i));
                if (filtered.size() == 100) break;
            }
        }else{

            for (int i = 0; i < list.size(); i += 2) {
                filtered.add(list.get(i));
                if (filtered.size() == 100) break;
            }
        }


        // 3. X轴：最后一个点为当前时间，依次往前推
        List<String> xAxis = new ArrayList<>();
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("HH:mm:ss");
        int intervalSec = 2;
        long now = System.currentTimeMillis();

        for (int i = 99; i >= 0; i--) {
            long ts = now - (long) i * intervalSec * 1000;
            xAxis.add(sdf.format(new Date(ts)));
        }



        // 4. Y轴
        String[] names = {
                "钢坯前上表面", "中上表面", "后上表面",
                "钢坯前下表面", "中下表面", "后下表面",
                "钢坯前芯部", "中芯部", "后芯部"
        };

        List<BaseVo> yAxis = new ArrayList<>();
        for (int i = 1; i <= 9; i++) {
            String fieldName = "data" + i;
            String name = names[i - 1];
            List<String> dataList = new ArrayList<>();

            for (BilletTempHistory h : filtered) {
                try {
                    Field field = BilletTempHistory.class.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    Object val = field.get(h);
                    dataList.add(val == null ? "" : val.toString());
                } catch (Exception e) {
                    dataList.add("");
                }
            }

            BaseVo vo = new BaseVo();
            vo.setName(name);
            vo.setData(dataList);
            yAxis.add(vo);
        }

        // 5. 封装返回
        BaseWaterVo baseWaterVo = new BaseWaterVo();
        baseWaterVo.setXAxis(xAxis);
        baseWaterVo.setYAxis(yAxis);

        return baseWaterVo;
    }

    /**
     * 导入钢坯温度历史记录
     *
     * @param voList    Excel 中解析出来的数据
     * @param type      类型（1：升温 2：降温）
     * @param importDay 导入日期
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 导入结果提示
     */
    @Override
    public String importBilletTempHistory(List<BilletTHistoryTemplateVo> voList,
                                          int type,
                                          Date importDay,
                                          String startTime,
                                          String endTime)
    {
        // 校验 Excel 是否为空
        if (voList == null || voList.isEmpty()) {
            throw new ServiceException("导入数据不能为空！");
        }

        int successCount = 0; // 成功条数
        List<BilletTempHistory> insertList = new ArrayList<>();

        // 遍历 Excel 数据，转换为实体类
        for (BilletTHistoryTemplateVo vo : voList) {
            BilletTempHistory entity = new BilletTempHistory();

            // 1. 拷贝 Excel 中的数据（温度字段）
            entity.setData1(vo.getData1());
            entity.setData2(vo.getData2());
            entity.setData3(vo.getData3());
            entity.setData4(vo.getData4());
            entity.setData5(vo.getData5());
            entity.setData6(vo.getData6());
            entity.setData7(vo.getData7());
            entity.setData8(vo.getData8());
            entity.setData9(vo.getData9());

            // 2. 设置公共参数（来自接口参数，而不是 Excel）
            entity.setType(type);
            entity.setImportDay(importDay);
            entity.setStartTime(startTime);
            entity.setEndTime(endTime);

            // 3. 加入待插入集合
            insertList.add(entity);
            successCount++;
        }

        // 4. 批量插入数据库（推荐用 MyBatis Plus 的 saveBatch 提高效率）
        if (!insertList.isEmpty()) {
            // 如果用 MyBatis Plus：
            // this.saveBatch(insertList);
            // 如果自定义 Mapper：
            this.saveBatch(insertList);
        }

        // 5. 返回导入结果
        return "成功导入 " + successCount + " 条数据";
    }

    /**
     * 根据参数查询钢坯温度历史记录并封装成 BaseWaterVo
     *
     * @param type      类型
     * @param importDay 导入日期
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return BaseWaterVo
     */
    @Override
    public BaseWaterVo getBilletTempHistoryChart(Integer type, Date importDay, String startTime, String endTime) {
        // 1. 查询数据
        List<BilletTempHistory> allData = billetTempHistoryMapper.selectByParams(type, importDay, startTime, endTime);
        if (allData == null || allData.isEmpty()) {
            return new BaseWaterVo();
        }

        // 2. 均分采样，最多50个点
        int total = allData.size();
        int points = Math.min(50, total);
        List<BilletTempHistory> sampled = new ArrayList<>();
        for (int i = 0; i < points; i++) {
            int index = (int) Math.round((double) i * (total - 1) / (points - 1));
            sampled.add(allData.get(index));
        }

        // 3. 生成 X 轴（首尾固定）
        List<String> xAxis = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        try {
            // 拼接 importDay + startTime / endTime
            SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");
            String dayStr = dayFormat.format(importDay);
            SimpleDateFormat fullFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Date start = fullFormat.parse(dayStr + " " + startTime);
            Date end = fullFormat.parse(dayStr + " " + endTime);

            xAxis.add(sdf.format(start)); // 第一个点固定为 startTime

            if (points > 2) {
                long totalMillis = end.getTime() - start.getTime();
                long stepMillis = totalMillis / (points - 1);

                for (int i = 1; i < points - 1; i++) {
                    long ts = start.getTime() + i * stepMillis;
                    xAxis.add(sdf.format(new Date(ts)));
                }
            }

            if (points > 1) {
                xAxis.add(sdf.format(end)); // 最后一个点固定为 endTime
            }
        } catch (ParseException e) {
            throw new RuntimeException("时间解析错误，应为 HH:mm 格式", e);
        }

        // 4. 生成 Y 轴
        String[] names = {
                "钢坯前上表面", "中上表面", "后上表面",
                "钢坯前下表面", "中下表面", "后下表面",
                "钢坯前芯部", "中芯部", "后芯部"
        };
        List<BaseVo> yAxis = new ArrayList<>();
        for (int i = 1; i <= 9; i++) {
            List<String> dataList = new ArrayList<>();
            for (BilletTempHistory h : sampled) {
                try {
                    Method getter = BilletTempHistory.class.getMethod("getData" + i);
                    Object val = getter.invoke(h);
                    dataList.add(val == null ? "" : val.toString());
                } catch (Exception e) {
                    dataList.add("");
                }
            }
            BaseVo vo = new BaseVo();
            vo.setName(names[i - 1]);
            vo.setData(dataList);
            yAxis.add(vo);
        }

        // 5. 封装返回
        BaseWaterVo baseWaterVo = new BaseWaterVo();
        baseWaterVo.setXAxis(xAxis);
        baseWaterVo.setYAxis(yAxis);

        return baseWaterVo;
    }

}
